package competition.cig.cs478.backprop;

import ch.idsia.mario.engine.sprites.Mario;
import ch.idsia.mario.environments.Environment;

import competition.cig.cs478.features.FeatureParser;

public class NetworkAdapter {
	private int jump_leftoff_count = 0;
	private int jump_lettoff_threshold = 20;
	private FeatureParser parser;
	
	public NetworkAdapter() {
		parser = new FeatureParser();
	}
	
	public int getInputCount() {
		return parser.getFeatureSet().length;
	}

	public int getOutputCount() {
		return Environment.numberOfButtons;
	}

	public double[] getInput(Environment observation) {
		parser.updateEnvironment(observation);
		return parser.getFeatureSet();
	}

	/**
	 * Reverse of getTargets; convert the network output into
	 * the action output of the mario controller.
	 * 
	 * @param network
	 * @return
	 */
	public boolean[] getOutput(double[] outputs) {
		boolean[] action = new boolean[Environment.numberOfButtons];
		action[Mario.KEY_LEFT]		= outputs[Mario.KEY_LEFT] > 0.5;
		action[Mario.KEY_RIGHT] 	= outputs[Mario.KEY_RIGHT] > 0.5;
		action[Mario.KEY_DOWN]		= outputs[Mario.KEY_DOWN] > 0.5;
		action[Mario.KEY_JUMP] 		= outputs[Mario.KEY_JUMP] > 0.0004;
		action[Mario.KEY_SPEED]		= outputs[Mario.KEY_SPEED] > 0.5;
		
		if (action[Mario.KEY_JUMP]) {
			if(++jump_leftoff_count > jump_lettoff_threshold) {
				action[Mario.KEY_JUMP] = false;
				jump_leftoff_count = 0;
			}
		} else {
			jump_leftoff_count = 0;
		}

		return action;
	}
	
	/**
	 * Converts the action output of the mario controller into
	 * the output target values expected by the Network
	 * 
	 * @param action
	 * @return
	 */
	public double[] getTargets(boolean[] action) {
		double[] targets = new double[Environment.numberOfButtons];
		targets[Mario.KEY_LEFT] 	= action[Mario.KEY_LEFT] ? 1.0 : 0.0;
		targets[Mario.KEY_RIGHT] 	= action[Mario.KEY_RIGHT] ? 1.0 : 0.0;
		targets[Mario.KEY_DOWN] 	= action[Mario.KEY_DOWN] ? 1.0 : 0.0;
		targets[Mario.KEY_JUMP] 	= action[Mario.KEY_JUMP] ? 1.0 : 0.0;
		targets[Mario.KEY_SPEED] 	= action[Mario.KEY_SPEED] ? 1.0 : 0.0;
		return targets;
	}
}
